Skip to content

Instantly share code, notes, and snippets.

@kilasuit
Last active January 7, 2022 11:19
Show Gist options
  • Save kilasuit/2932702c954fb45b0442e717a14920e7 to your computer and use it in GitHub Desktop.
Save kilasuit/2932702c954fb45b0442e717a14920e7 to your computer and use it in GitHub Desktop.
PowerApps nonsense powershell fix
function Get-AdminPowerAppsUserDetails
{
<#
.SYNOPSIS
Downloads the user details into specified filepath
.DESCRIPTION
The Get-AdminPowerAppsUserDetails downloads the powerApps user details into the specified path file
Use Get-Help Get-AdminPowerAppsUserDetails -Examples for more detail.
.PARAMETER UserPrincipalName
The user principal name
.PARAMETER OutputFilePath
The Output FilePath
.EXAMPLE
Get-AdminPowerAppsUserDetails -OutputFilePath C:\Users\testuser\userdetails.json
Donloads the details of calling user into specified path file C:\Users\testuser\userdetails.json
.EXAMPLE
Get-AdminPowerAppsUserDetails -UserPrincipalName foo@bar.com -OutputFilePath C:\Users\testuser\userdetails.json
downloads the details of user with principal name foo@bar.com into specified file path C:\Users\testuser\userdetails.json
#>
param
(
[Parameter(Mandatory = $false)]
[string]$UserPrincipalName = $null,
[Parameter(Mandatory = $true)]
[string]$OutputFilePath = $null,
[Parameter(Mandatory = $false)]
[string]$ApiVersion = "2016-11-01"
)
process
{
#Construct the body
$requestbody = $null
if (-not [string]::IsNullOrWhiteSpace($UserPrincipalName))
{
$requestbody = @{
userPrincipalName = $UserPrincipalName
}
}
#first post call would just return the status 'ACCEPTED' and Location in Headers
#keep calling Get Location Uri until the job gets finished and once the job gets finished it returns http 'OK' and SAS uri otherwise 'ACCEPTED'
$route = "https://{powerAppsEndpoint}/providers/Microsoft.PowerApps/scopes/admin/exportHiddenUserData?api-version={apiVersion}";
#Kick-off the job
$getUserDataJobKickOffResponse = InvokeApiNoParseContent -Route $route -Method POST -Body $requestbody -ThrowOnFailure -ApiVersion $ApiVersion -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true)
$statusUrl = $getUserDataJobKickOffResponse.Headers['Location']
#Wait until job is completed
if (-not [string]::IsNullOrWhiteSpace($statusUrl))
{
while($getJobCompletedResponse.StatusCode -ne 200)
{
Start-Sleep -s 3
$getJobCompletedResponse = InvokeApiNoParseContent -Route $statusUrl -Method GET -ThrowOnFailure
}
CreateHttpResponse($getJobCompletedResponse)
$responseBody = ConvertFrom-Json $getJobCompletedResponse.Content
try {
$downloadCsvResponse = Invoke-WebRequest -Uri $responseBody -OutFile $OutputFilePath
Write-Verbose "Downloaded to specified file"
} catch {
Write-Host "Error while downloading"
$response = $_.Exception.Response
if ($_.ErrorDetails)
{
$errorResponse = ConvertFrom-Json $_.ErrorDetails;
$code = $response.StatusCode
$message = $errorResponse.error.message
Write-Verbose "Status Code: '$code'. Message: '$message'"
}
}
}
}
}
function Get-AdminPowerAppsUserDetails
{
<#
.SYNOPSIS
Downloads the user details and outputs to the pipeline or can be output to a file in a given filepath
.DESCRIPTION
The Get-AdminPowerAppsUserDetails downloads the powerApps user details into the specified path file
Use Get-Help Get-AdminPowerAppsUserDetails -Examples for more detail.
.PARAMETER UserPrincipalName
The user principal name
.PARAMETER OutputFilePath
The Output FilePath
.EXAMPLE
Get-AdminPowerAppsUserDetails
Donloads the details of calling user & outputs it as an object
.EXAMPLE
Get-AdminPowerAppsUserDetails -OutputFilePath C:\Users\testuser\userdetails.json
Donloads the details of calling user into specified path file C:\Users\testuser\userdetails.json
.EXAMPLE
Get-AdminPowerAppsUserDetails -UserPrincipalName foo@bar.com -OutputFilePath C:\Users\testuser\userdetails.json
downloads the details of user with principal name foo@bar.com into specified file path C:\Users\testuser\userdetails.json
#>
param
(
[Parameter(Mandatory = $false)]
[string]$UserPrincipalName = $null,
[Parameter(Mandatory = $false)]
[string]$OutputFilePath = $null,
[Parameter(Mandatory = $false)]
[string]$ApiVersion = "2016-11-01"
)
process
{
#Construct the body
$requestbody = $null
if (-not [string]::IsNullOrWhiteSpace($UserPrincipalName))
{
$requestbody = @{
userPrincipalName = $UserPrincipalName
}
}
#first post call would just return the status 'ACCEPTED' and Location in Headers
#keep calling Get Location Uri until the job gets finished and once the job gets finished it returns http 'OK' and SAS uri otherwise 'ACCEPTED'
$route = "https://{powerAppsEndpoint}/providers/Microsoft.PowerApps/scopes/admin/exportHiddenUserData?api-version={apiVersion}";
#Kick-off the job
$getUserDataJobKickOffResponse = InvokeApiNoParseContent -Route $route -Method POST -Body $requestbody -ThrowOnFailure -ApiVersion $ApiVersion -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true)
$statusUrl = $getUserDataJobKickOffResponse.Headers['Location']
#Wait until job is completed
if (-not [string]::IsNullOrWhiteSpace($statusUrl))
{
while($getJobCompletedResponse.StatusCode -ne 200)
{
Start-Sleep -s 3
$getJobCompletedResponse = InvokeApiNoParseContent -Route $statusUrl -Method GET -ThrowOnFailure
}
CreateHttpResponse($getJobCompletedResponse)
$responseBody = ConvertFrom-Json $getJobCompletedResponse.Content
try {
$downloadCsvResponse = Invoke-WebRequest -Uri $responseBody
If($OutputFilePath) {
$downloadCsvResponse | Out-File -FilePath $OutputFilePath -Force
Write-Verbose "Downloaded to specified file"
} else {
$downloadCsvResponse
}
} catch {
Write-Host "Error while downloading"
$response = $_.Exception.Response
if ($_.ErrorDetails)
{
$errorResponse = ConvertFrom-Json $_.ErrorDetails;
$code = $response.StatusCode
$message = $errorResponse.error.message
Write-Verbose "Status Code: '$code'. Message: '$message'"
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment