Forum Discussion
Power BI REST API via Powershell: Create Datasource
The credentials from credentialDetails need to be encripted unsing RSA algorithm before calling the api. I've used an alghorthim posted in https://community.powerbi.com/t5/Developer/How-do-I-update-the-Credentials-after-I-upload-a-report-to-POWER/td-p/223243 and converted it to powershell. The algorithm from https://docs.microsoft.com/en-us/power-bi/developer/encrypt-credentials is also good. Also the server name needs to have double the amount of "\" charahters to work.
function CreateDatasourceForGateway([guid]$GatewayId,
[string]$DatasourceName,
[string]$TenantServer,
[string]$TenantDatabase,
[string]$TenantDataSourceUser,
[string]$TenantDataSourcePassword) {
$gateway = Invoke-PowerBIRestMethod `
-Url "https://api.powerbi.com/v1.0/myorg/gateways/$GatewayId" `
-Method GET ` | ConvertFrom-Json
$datasourceDetails = ConvertTo-Json -Depth 4 -InputObject $(@{
dataSourceType = "Sql"
connectionDetails = '{"server":"'+$TenantServer.Replace("\","\\")+'","database":"'+$TenantDatabase+'"}'
datasourceName = $DatasourceName
credentialDetails = @{
credentialType = "Basic"
credentials = Encript `
-Username $TenantDataSourceUser `
-Password $TenantDataSourcePassword `
-GatewayExponent $gateway.publicKey.exponent `
-GatewayModulus $gateway.publicKey.modulus
encryptedConnection = "Encrypted"
encryptionAlgorithm = "RSA-OAEP"
privacyLevel = "None"
}
})
$result = Invoke-PowerBIRestMethod `
-Url "https://api.powerbi.com/v1.0/myorg/gateways/$GatewayId/datasources" `
-Method POST `
-Body $datasourceDetails
}
function Encript([string]$Username,[string]$Password,[string]$GatewayExponent,[string]$GatewayModulus) {
$segmentLength = 85
$encryptedLength = 128
$plaintTxt = '{"credentialData":[{"value":"'+$Username+'","name":"username"},{"value":"'+$Password+'","name":"password"}]}'
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider ($encryptedLength * 8)
$parameters = $rsa.ExportParameters($false)
$parameters.Exponent = [System.Convert]::FromBase64String($GatewayExponent)
$parameters.Modulus = [System.Convert]::FromBase64String($GatewayModulus)
$rsa.ImportParameters($parameters)
$plainTextArray = [System.Text.Encoding]::UTF8.GetBytes($plaintTxt)
$hasIncompleteSegment = $plainTextArray.Length % $segmentLength -ne 0
$segmentNumber = If (-not $hasIncompleteSegment) {[int]($plainTextArray.Length / $segmentLength)} Else {[int]($plainTextArray.Length / $segmentLength) + 1}
$encryptedData = [System.Byte[]]::CreateInstance([System.Byte],$segmentNumber * $encryptedLength)
[int]$encryptedDataPosition = 0;
For ($i=0; $i -lt $segmentNumber; $i++) {
$lengthToCopy = If ($i -eq ($segmentNumber - 1) -and $hasIncompleteSegment) {$plainTextArray.Length % $segmentLength} Else {$segmentLength}
$segment = [System.Byte[]]::CreateInstance([System.Byte],$lengthToCopy)
[System.Array]::Copy($plainTextArray,$i*$segmentLength,$segment,0,$lengthToCopy)
$segmentEncryptedResult = $rsa.Encrypt($segment, $true)
[System.Array]::Copy($segmentEncryptedResult,0,$encryptedData,$encryptedDataPosition,$segmentEncryptedResult.Length)
$encryptedDataPosition += $segmentEncryptedResult.Length;
}
return [System.Convert]::ToBase64String($encryptedData)
}
Connect-PowerBIServiceAccount
CreateDatasourceForGateway `
-GatewayId $GatewayId `
-DatasourceName "$TenantReportPrefix Datasource"`
-TenantServer $TenantServer `
-TenantDatabase $TenantDatabase `
-TenantDataSourceUser $TenantDataSourceUser `
-TenantDataSourcePassword $TenantDataSourcePassword
Hi Alex,
I am getting this weird error message when used your code.
"
Invoke-PowerBIRestMethod : One or more errors occurred.
At line:29 char:15
+ $result = Invoke-PowerBIRestMethod `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (Microsoft.Power...werBIRestMethod:InvokePowerBIRestMethod) [Invoke-PowerBIRestMethod], AggregateException
+ FullyQualifiedErrorId : One or more errors occurred.,Microsoft.PowerBI.Commands.Profile.InvokePowerBIRestMethod
"
With resolve-azerror -last
"
WARNING: Breaking changes in the cmdlet 'Resolve-AzError' :
WARNING: - The `Resolve-Error` alias will be removed in a future release. Please change any scripts that use this alias to use `Resolve-AzError` instead.
WARNING: NOTE : Go to https://aka.ms/azps-changewarnings for steps to suppress this breaking change warning, and other information on breaking changes in Azure PowerShell.
HistoryId: 7
Message : Response status code does not indicate success: 400 (Bad Request).
StackTrace : at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at Microsoft.PowerBI.Commands.Profile.InvokePowerBIRestMethod.<InvokeRestMethod>d__31.MoveNext()
Exception : System.Net.Http.HttpRequestException
InvocationInfo : {Invoke-PowerBIRestMethod}
Line : $result = Invoke-PowerBIRestMethod `
Position : At line:29 char:15
+ $result = Invoke-PowerBIRestMethod `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
HistoryId : 7
The Azure PowerShell team is listening, please let us know how we are doing: https://aka.ms/azpssurvey?Q_CHL=FEEDBACK.
"
Do I need to have Power Bi Admin permissions ?
I have full administrative permissions on Power Bi gateway where trying to build this data source.