From ab606a5b8374d0b7ad2ff90b06954d8d2a6ebf75 Mon Sep 17 00:00:00 2001 From: Kamil Nowinski Date: Thu, 11 Dec 2025 23:06:14 +0000 Subject: [PATCH 1/4] Fixed the bug related to session configs after recent changes to PSFabricConfig --- source/Private/Confirm-TokenState.ps1 | 2 +- source/Private/Set-FabConfig.ps1 | 4 +++- .../Public/Capacity/Get-FabricCapacityState.ps1 | 17 +++++++++-------- .../Public/Capacity/Resume-FabricCapacity.ps1 | 7 ++++--- .../Public/Capacity/Suspend-FabricCapacity.ps1 | 3 ++- source/Public/Connect-FabricAccount.ps1 | 2 +- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/source/Private/Confirm-TokenState.ps1 b/source/Private/Confirm-TokenState.ps1 index e89fdb5..d08fc07 100644 --- a/source/Private/Confirm-TokenState.ps1 +++ b/source/Private/Confirm-TokenState.ps1 @@ -25,7 +25,7 @@ function Confirm-TokenState { param () # Refresh the global FabricConfig variable to be backwards compatible - $script:FabricConfig = Get-PSFConfigValue 'FabricTools.FabricApi.BaseApiUrl' + $script:FabricConfig.BaseUrl = Get-PSFConfigValue 'FabricTools.FabricApi.BaseUrl' Write-Message -Message "Validating token..." -Level Verbose diff --git a/source/Private/Set-FabConfig.ps1 b/source/Private/Set-FabConfig.ps1 index 8cc16b7..341cfe4 100644 --- a/source/Private/Set-FabConfig.ps1 +++ b/source/Private/Set-FabConfig.ps1 @@ -1,4 +1,6 @@ -Set-PSFConfig -Name 'FabricTools.FabricApi.BaseApiUrl' -Value 'https://api.fabric.microsoft.com/v1' +Write-Verbose "Setting FabricTools configuration defaults..." + +Set-PSFConfig -Name 'FabricTools.FabricApi.BaseUrl' -Value 'https://api.fabric.microsoft.com/v1' Set-PSFConfig -Name 'FabricTools.FabricApi.ResourceUrl' -Value 'https://api.fabric.microsoft.com' Set-PSFConfig -Name 'FabricTools.FabricApi.TenantId' Set-PSFConfig -Name 'FabricTools.FabricApi.ContentType' -Value 'application/json; charset=utf-8' diff --git a/source/Public/Capacity/Get-FabricCapacityState.ps1 b/source/Public/Capacity/Get-FabricCapacityState.ps1 index 182ad89..8b805bd 100644 --- a/source/Public/Capacity/Get-FabricCapacityState.ps1 +++ b/source/Public/Capacity/Get-FabricCapacityState.ps1 @@ -6,20 +6,20 @@ Retrieves the state of a specific capacity. .DESCRIPTION The Get-FabricCapacityState function retrieves the state of a specific capacity. It supports multiple aliases for flexibility. -.PARAMETER subscriptionID +.PARAMETER SubscriptionID The ID of the subscription. This is a mandatory parameter. This is a parameter found in Azure, not Fabric. -.PARAMETER resourcegroup +.PARAMETER ResourceGroup The resource group. This is a mandatory parameter. This is a parameter found in Azure, not Fabric. -.PARAMETER capacity +.PARAMETER Capacity The capacity. This is a mandatory parameter. This is a parameter found in Azure, not Fabric. .EXAMPLE This example retrieves the state of a specific capacity given the subscription ID, resource group, and capacity. ```powershell - Get-FabricCapacityState -subscriptionID "your-subscription-id" -resourcegroupID "your-resource-group" -capacityID "your-capacity" + Get-FabricCapacityState -SubscriptionID "your-subscription-id" -ResourceGroup "your-resource-group" -Capacity "your-capacity" ``` .NOTES @@ -36,9 +36,9 @@ Author: Ioana Bouariu # Define mandatory parameters for the subscription ID, resource group, and capacity. Param ( [Parameter(Mandatory = $true)] - [guid]$subscriptionID, + [guid]$SubscriptionID, [Parameter(Mandatory = $true)] - [string]$resourcegroup, + [string]$ResourceGroup, [Parameter(Mandatory = $true)] [string]$capacity ) @@ -46,10 +46,11 @@ Author: Ioana Bouariu Confirm-TokenState $AzureBaseApiUrl = Get-PSFConfigValue 'FabricTools.AzureApi.BaseUrl' + $headers = Get-PSFConfigValue 'FabricTools.AzureSession.Headers' # Define the URL for the GET request. - $getCapacityState = "$AzureBaseApiUrl/subscriptions/$subscriptionID/resourceGroups/$resourcegroup/providers/Microsoft.Fabric/capacities/$capacity/?api-version=2022-07-01-preview" + $getCapacityState = "$AzureBaseApiUrl/subscriptions/$SubscriptionID/resourceGroups/$ResourceGroup/providers/Microsoft.Fabric/capacities/$Capacity/?api-version=2022-07-01-preview" # Make the GET request and return the response. - return Invoke-RestMethod -Method GET -Uri $getCapacityState -Headers $script:AzureSession.HeaderParams -ErrorAction Stop + return Invoke-RestMethod -Method GET -Uri $getCapacityState -Headers $headers -ErrorAction Stop } diff --git a/source/Public/Capacity/Resume-FabricCapacity.ps1 b/source/Public/Capacity/Resume-FabricCapacity.ps1 index 6d58141..6ec812a 100644 --- a/source/Public/Capacity/Resume-FabricCapacity.ps1 +++ b/source/Public/Capacity/Resume-FabricCapacity.ps1 @@ -12,14 +12,14 @@ function Resume-FabricCapacity { .PARAMETER ResourceGroup The resource group. This is a mandatory parameter. This is a parameter found in Azure, not Fabric. - .PARAMETER capacity + .PARAMETER Capacity The capacity. This is a mandatory parameter. This is a parameter found in Azure, not Fabric. .EXAMPLE This example resumes a capacity given the subscription ID, resource group, and capacity. ```powershell - Resume-FabricCapacity -subscriptionID "your-subscription-id" -ResourceGroup "your-resource-group" -capacityID "your-capacity" + Resume-FabricCapacity -SubscriptionID "your-subscription-id" -ResourceGroup "your-resource-group" -Capacity "your-capacity" ``` .NOTES @@ -44,12 +44,13 @@ function Resume-FabricCapacity { Confirm-TokenState $AzureBaseApiUrl = Get-PSFConfigValue 'FabricTools.AzureApi.BaseUrl' + $headers = Get-PSFConfigValue 'FabricTools.AzureSession.Headers' # Define the URI for the request. $resumeCapacity = "$AzureBaseApiUrl/subscriptions/$SubscriptionID/resourceGroups/$ResourceGroup/providers/Microsoft.Fabric/capacities/$Capacity/resume?api-version=2022-07-01-preview" # Make a GET request to the URI and return the response. if ($PSCmdlet.ShouldProcess("Resume capacity $Capacity")) { - return Invoke-RestMethod -Method POST -Uri $resumeCapacity -Headers $script:AzureSession.HeaderParams -ErrorAction Stop + return Invoke-RestMethod -Method POST -Uri $resumeCapacity -Headers $headers -ErrorAction Stop } } diff --git a/source/Public/Capacity/Suspend-FabricCapacity.ps1 b/source/Public/Capacity/Suspend-FabricCapacity.ps1 index efa0991..af5a0bf 100644 --- a/source/Public/Capacity/Suspend-FabricCapacity.ps1 +++ b/source/Public/Capacity/Suspend-FabricCapacity.ps1 @@ -45,13 +45,14 @@ Author: Ioana Bouariu Confirm-TokenState $AzureBaseApiUrl = Get-PSFConfigValue 'FabricTools.AzureApi.BaseUrl' + $headers = Get-PSFConfigValue 'FabricTools.AzureSession.Headers' # Define the URI for the request. $suspendCapacity = "$AzureBaseApiUrl/subscriptions/$SubscriptionID/resourceGroups/$ResourceGroup/providers/Microsoft.Fabric/capacities/$Capacity/suspend?api-version=2023-11-01" # Make a GET request to the URI and return the response. if ($PSCmdlet.ShouldProcess("Suspend capacity $capacity")) { - return Invoke-RestMethod -Method POST -Uri $suspendCapacity -Headers $script:AzureSession.HeaderParams -ErrorAction Stop + return Invoke-RestMethod -Method POST -Uri $suspendCapacity -Headers $headers -ErrorAction Stop } } diff --git a/source/Public/Connect-FabricAccount.ps1 b/source/Public/Connect-FabricAccount.ps1 index c68c785..9c776f0 100644 --- a/source/Public/Connect-FabricAccount.ps1 +++ b/source/Public/Connect-FabricAccount.ps1 @@ -124,7 +124,7 @@ function Connect-FabricAccount { $azContext = Get-AzContext } - Write-Message "Connected: $($azContext.Account)" -Level Verbose + Write-Message "Connected: $($azContext.Account)" -Level Info if ($PSCmdlet.ShouldProcess("Setting Fabric authentication token and headers for $($azContext.Account)")) { $ResourceUrl = Get-PSFConfigValue -FullName 'FabricTools.FabricApi.ResourceUrl' From 8b5bc7b40b808bbc59ac480e059a30789cfbd136 Mon Sep 17 00:00:00 2001 From: Kamil Nowinski Date: Sat, 13 Dec 2025 15:42:44 +0000 Subject: [PATCH 2/4] Now you can log in using SPN where secret is provided as String #164 --- CHANGELOG.md | 1 + source/Public/Connect-FabricAccount.ps1 | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a6bb11..b78b341 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed bug in `Update-FabricSemanticModelDefinition` - Uri was incorrect when a platform file exists - Name of new SQL database will be shown (#169) +- Logging in with a Service Principal does not work (#164) ### Deprecated diff --git a/source/Public/Connect-FabricAccount.ps1 b/source/Public/Connect-FabricAccount.ps1 index 9c776f0..0976073 100644 --- a/source/Public/Connect-FabricAccount.ps1 +++ b/source/Public/Connect-FabricAccount.ps1 @@ -14,7 +14,7 @@ function Connect-FabricAccount { The Client ID (AppId) of the service principal used for authentication. .PARAMETER ServicePrincipalSecret - The **secure string** representing the service principal secret. + String representing the service principal secret. .PARAMETER Credential A PSCredential object representing a user credential (username and secure password). @@ -70,9 +70,9 @@ function Connect-FabricAccount { [Alias('AppId')] [guid] $ServicePrincipalId, - [Parameter(Mandatory = $false, HelpMessage = "Secure secret of the service principal.")] + [Parameter(Mandatory = $false, HelpMessage = "Secret of the service principal.")] [Alias('AppSecret')] - [SecureString] $ServicePrincipalSecret, + [String] $ServicePrincipalSecret, [Parameter(Mandatory = $false, HelpMessage = "User credential.")] [PSCredential] $Credential, @@ -103,12 +103,13 @@ function Connect-FabricAccount { if (!$azContext) { if ($ServicePrincipalId) { Write-Message "Connecting to Azure Account using provided servicePrincipalId..." -Level Verbose - $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ServicePrincipalId, $ServicePrincipalSecret + $ServicePrincipalSecretSecure = ($ServicePrincipalSecret | ConvertTo-SecureString -AsPlainText -Force) + $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ServicePrincipalId, $ServicePrincipalSecretSecure $null = Connect-AzAccount -ServicePrincipal -TenantId $TenantId -Credential $credential } elseif ($null -ne $Credential) { Write-Message "Connecting to Azure Account using provided credential..." -Level Verbose - $null = Connect-AzAccount -Credential $Credential -Tenant $TenantId + $null = Connect-AzAccount -ServicePrincipal -Credential $Credential -Tenant $TenantId } else { Write-Message "Connecting to Azure Account using current user..." -Level Verbose @@ -151,6 +152,5 @@ function Connect-FabricAccount { } } - end { - } + end { } } From db658f860c512cdb72dc8f33e834aedd4aa0d772 Mon Sep 17 00:00:00 2001 From: Kamil Nowinski Date: Sat, 13 Dec 2025 16:43:04 +0000 Subject: [PATCH 3/4] SecureString is OK --- source/Public/Connect-FabricAccount.ps1 | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/source/Public/Connect-FabricAccount.ps1 b/source/Public/Connect-FabricAccount.ps1 index 0976073..c3bafa1 100644 --- a/source/Public/Connect-FabricAccount.ps1 +++ b/source/Public/Connect-FabricAccount.ps1 @@ -14,7 +14,7 @@ function Connect-FabricAccount { The Client ID (AppId) of the service principal used for authentication. .PARAMETER ServicePrincipalSecret - String representing the service principal secret. + The **secure string** representing the service principal secret. .PARAMETER Credential A PSCredential object representing a user credential (username and secure password). @@ -70,9 +70,9 @@ function Connect-FabricAccount { [Alias('AppId')] [guid] $ServicePrincipalId, - [Parameter(Mandatory = $false, HelpMessage = "Secret of the service principal.")] + [Parameter(Mandatory = $false, HelpMessage = "Secure secret of the service principal.")] [Alias('AppSecret')] - [String] $ServicePrincipalSecret, + [SecureString] $ServicePrincipalSecret, [Parameter(Mandatory = $false, HelpMessage = "User credential.")] [PSCredential] $Credential, @@ -91,7 +91,12 @@ function Connect-FabricAccount { if ($PSBoundParameters.ContainsKey('AppSecret') -and -not $PSBoundParameters.ContainsKey('AppId')) { Write-Message -Message "AppId is required when using AppSecret." -Level Error - throw "AppId is required when using AppId." + throw "AppId is required when using AppSecret." + } + # Warn if both Credential and AppId are provided + if ($PSBoundParameters.ContainsKey('Credential') -and $PSBoundParameters.ContainsKey('AppId')) + { + Write-Message -Message "Provided Credential will be ignored when AppId/ServicePrincipalId is also provided." -Level Warning } } @@ -102,9 +107,8 @@ function Connect-FabricAccount { } if (!$azContext) { if ($ServicePrincipalId) { - Write-Message "Connecting to Azure Account using provided servicePrincipalId..." -Level Verbose - $ServicePrincipalSecretSecure = ($ServicePrincipalSecret | ConvertTo-SecureString -AsPlainText -Force) - $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ServicePrincipalId, $ServicePrincipalSecretSecure + Write-Message "Connecting to Azure Account using provided ServicePrincipalId..." -Level Verbose + $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ServicePrincipalId, $ServicePrincipalSecret $null = Connect-AzAccount -ServicePrincipal -TenantId $TenantId -Credential $credential } elseif ($null -ne $Credential) { From a68af49d1561b5d4fbe77a63650ed69a0d30273a Mon Sep 17 00:00:00 2001 From: Kamil Nowinski Date: Sat, 13 Dec 2025 16:51:59 +0000 Subject: [PATCH 4/4] Updated examples for Connect-FabricAccount #164 --- source/Public/Connect-FabricAccount.ps1 | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/source/Public/Connect-FabricAccount.ps1 b/source/Public/Connect-FabricAccount.ps1 index c3bafa1..077294b 100644 --- a/source/Public/Connect-FabricAccount.ps1 +++ b/source/Public/Connect-FabricAccount.ps1 @@ -38,10 +38,28 @@ function Connect-FabricAccount { ``` .EXAMPLE - Connects as Service Principal using id and secret + Connects as Service Principal using AppId and secret ```powershell - Connect-FabricAccount -TenantId 'xxx' -ServicePrincipalId 'appId' -ServicePrincipalSecret $secret + $TenantID = '12345678-1234-1234-1234-123456789012' + $ServicePrincipalId = '4cbbe76e-1234-1234-0000-ffffffffffff' + $ServicePrincipalSecret = 'xyz' + + $ServicePrincipalSecretSecure = ($ServicePrincipalSecret | ConvertTo-SecureString -AsPlainText -Force) + Connect-FabricAccount -TenantId $TenantID -ServicePrincipalId $ServicePrincipalId -ServicePrincipalSecret $ServicePrincipalSecretSecure -Reset + ``` + +.EXAMPLE + Connects as Service Principal using credential object + + ```powershell + $TenantID = '12345678-1234-1234-1234-123456789012' + $ServicePrincipalId = '4cbbe76e-1234-1234-0000-ffffffffffff' + $ServicePrincipalSecret = 'xyz' + + $ServicePrincipalSecretSecure = ($ServicePrincipalSecret | ConvertTo-SecureString -AsPlainText -Force) + $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ServicePrincipalId, $ServicePrincipalSecretSecure + Connect-FabricAccount -TenantId $TenantID -Credential $credential -Verbose -Reset ``` .OUTPUTS