How to extract all PowerBI users and workspace access using the PowerBI API or Azure Portal? - azure

New to Power BI. Trying to get a report of the Users who have access for each Dashboards. Any pointers would be helpful.
Thanks in advance!

Below is the script I created. First change the username and password for your PowerBI credentials. The script collects the results and then opens two Out Grid windows (Workspaces and Workspace Users). You can then copy/paste the grid results into excel. This doesn't export shared reports and dashboards.
I have two PBI powershell modules installed. I think this script uses only the MicrosoftPowerBIMgmt.
Check if you have the PBI modules.
get-module -ListAvailable | where {$_.Name -like '*BI*'}
And to check for the cmdlets available.
get-command -module MicrosoftPowerBIMgmt.Admin | sort CommandType, name
get-command -module MicrosoftPowerBIMgmt.Capacities | sort CommandType, name
get-command -module MicrosoftPowerBIMgmt.Data | sort CommandType, name
get-command -module MicrosoftPowerBIMgmt.Profile | sort CommandType, name
get-command -module MicrosoftPowerBIMgmt.Reports | sort CommandType, name
get-command -module MicrosoftPowerBIMgmt.Workspaces | sort CommandType, name
get-command -module PowerBIPS | sort CommandType, name
PBI WORKSPACES & PERMISSIONS
#****************
#------------------------------------------------------
# --> PBI WORKSPACES & PERMISSIONS
#
# Export PBI results to grid for copy/paste to Excel table
# * All groups (Active/Deleted)
# * All workspaces (Active)
# * All workspace permissions
#
# RestAPI call for each workspace (Group Users)
# * https://learn.microsoft.com/en-us/rest/api/power-bi/groups/getgroupusers
#
#------------------------------------------------------
#****************
#------------------------------------------------------
# --> PBI Connection
#------------------------------------------------------
Write-Host " PBI credentials ..." -ForegroundColor Yellow -BackgroundColor DarkGreen
## PBI credentials
$password = "myPassword" | ConvertTo-SecureString -asPlainText -Force
$username = "myemail#domain.com"
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
## PBI connect
Connect-PowerBIServiceAccount -Credential $credential
# Login-PowerBI
#****************
#------------------------------------------------------
# --> Workspace info
#
# * Get-PowerBIWorkspace > "WARNING: Defaulted to show top 100 workspaces. Use -First & -Skip or -All to retrieve more results."
# * Grid exported for workspaces
#------------------------------------------------------
Write-Host " Workspace info ..." -ForegroundColor Yellow -BackgroundColor DarkGreen
## List all groups, Select ID desired for Variables section
## PBIWorkspace properties values are NULL if Scope is not set to Organization
# Get-PowerBIWorkspace -Scope Organization -Filter "tolower(name) eq 'BI Team POC - DEV'"
# SET
$Groups = Get-PowerBIWorkspace -Scope Organization -All | SORT #{Expression="Type"; Descending=$True}, Name
$Groups_deleted = $Groups | SELECT Id, Name, Type, State | WHERE State -EQ 'Deleted'
$Groups = $Groups | SELECT Id, Name, Type, State | WHERE State -NE 'Deleted'
$GroupWorkspaces = $Groups | WHERE Type -eq 'Workspace'
# PRINT
$Groups_deleted | Select Id, Name, Type, State | ft –auto
$Groups | Select Id, Name, Type, State | ft –auto
$GroupWorkspaces | Select Id, Name, Type | ft –auto
Get-PowerBIWorkspace -Scope Organization -Name "BI Team Sandbox" | Select Id, Name, Type | ft –auto
# OUT GRID
$GroupsWorkspaces | Select Id, Name, Type | Out-GridView
$Groups | Select Id, Name, Type | Out-GridView
$Groups_deleted | Select Id, Name, Type, State | Out-GridView
#------------------------------------------------------
## LOOP FOLDERS ##################
# * RestAPI call for each workspace (Group Users)
# * Grid exported for workspace user access
#------------------------------------------------------
# Clear variable before loop to reseat array data collector
clear-variable -name WorkspaceUsers
Write-Host " Looping ..." -ForegroundColor Yellow -BackgroundColor DarkGreen
foreach ($GroupWorkspaceId in $GroupWorkspaces.Id) {
$WorkspaceObject = Get-PowerBIWorkspace -Scope Organization -Id $GroupWorkspaceId
$pbiURL = "https://api.powerbi.com/v1.0/myorg/groups/$GroupWorkspaceId/users"
$WorkspaceObject | Select Id, Name, Type | ft –auto
Write-Host ($WorkspaceObject.Name +" | "+ $WorkspaceObject.Type) -ForegroundColor White -BackgroundColor Blue
Write-Host $GroupWorkspaceId -ForegroundColor White -BackgroundColor Blue
Write-Host $pbiURL -ForegroundColor White -BackgroundColor Blue
#****************
#------------------------------------------------------
# --> 1. API Call for WORKSPACE USERS
#------------------------------------------------------
Write-Host " API Call ..." -ForegroundColor Yellow -BackgroundColor DarkGreen
## API call
$resultJson = Invoke-PowerBIRestMethod –Url $pbiURL –Method GET
$resultObject = ConvertFrom-Json -InputObject $resultJson
## Collect data fields for each loop
$WorkspaceUsers += $resultObject.Value |
SELECT #{n='WorkspaceId';e={$GroupWorkspaceId}},
#{n='Workspace';e={$WorkspaceObject.Name}},
displayName,
emailAddress,
#{n='UserRole';e={$_.groupUserAccessRight}},
#{n='Principle';e={$_.principalType}} |
SELECT Workspace, displayName, UserRole, Principle, emailAddress |
SORT UserRole, displayName
## Print loop results
$WorkspaceUsers | ft -auto | Where{$_.WorkspaceId -eq $GroupWorkspaceId}
clear-variable -name resultJson
clear-variable -name resultObject
}
## END LOOP ##################
#------------------------------------------------------
## Export user access for all workspaces
$WorkspaceUsers | SORT Workspace, UserRole, displayName | Out-GridView

You can use Get-PowerBIWorkspace from Microsoft Power BI Cmdlets to get list of workspaces and then list the members of the underlying Office 365 group (unless you are using the new preview workspaces, which has no underlying Office 365 group) using Get-UnifiedGroup cmdlet. To be able to use it, you need to Connect to Exchange Online PowerShell. Then enumerate the groups, enumerate current group members, and export them to a CSV (or process the result the way you want). If you have rights, provide -Scope Organization parameter, or omit it to get a list of your workspaces.
Import-Module MicrosoftPowerBIMgmt
$password = "xxxxxxxx" | ConvertTo-SecureString -asPlainText -Force
$username = "xxxxxxxx#example.com"
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
Connect-PowerBIServiceAccount -Credential $credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange `
-ConnectionUri https://outlook.office365.com/powershell-liveid/ `
-Credential $credential `
-Authentication Basic `
-AllowRedirection
Import-PSSession $Session
$Groups = Get-PowerBIWorkspace #-Scope Organization
$Groups | ForEach-Object {
$group = $_
Get-UnifiedGroupLinks -Identity $group.Name -LinkType Members -ResultSize Unlimited | ForEach-Object {
$member = $_
New-Object -TypeName PSObject -Property #{
Member = $member.Name
Group = $group.Name
}
}
} | Export-CSV "D:\\PowerBIGroupMembers.csv" -NoTypeInformation -Encoding UTF8
Remove-PSSession $Session
Disconnect-PowerBIServiceAccount

Related

azure ad group name and member count

i have a lots of azure ad group with this format "AA - BB - xxx" where xxx can be anything.
i am trying to do a report on how many members in this azure ad group by display the azure ad group name and the number of its members.
i know to do 1 group is using this:
(Get-AzureADGroupMember -all 1 -ObjectId "xxxxx").count
how do i do lots of group with same group naming format to display its name and number of members?
thanks.
You need to first get all groups with such a name and then loop over the resulting list like:
$result = Get-AzureADGroup -Filter "startswith(DisplayName, 'AA - BB -')" -All $true | ForEach-Object {
[PsCustomObject]#{
Group = $_.DisplayName
MemberCount = #(Get-AzureADGroupMember -ObjectId $_.ObjectId -All $true).Count
}
}
# output on screen
$result | Format-Table -AutoSize
# save as Csv file
$result | Export-Csv -Path 'X:\PathTo\GroupMemberCount.csv' -NoTypeInformation
Apparently, the startswith() Filter on Get-AzureADGroup does not always return the wanted results (depending on the version of the OData language??).
In that case do
$result = Get-AzureADGroup | Where-Object {$_.DisplayName -like 'AA - BB -*'} | ForEach-Object {...}

Unable to query Azure WAF logs

I have been asked to use Powershell to query Azure WAS logs for blocked requests. I found https://cloudrobots.net/2021/03/07/download-azure-wav-v2-blocking-logs-w-powershell/ but am having some trouble.
First, I created a new service principal and assigned it the Contributor role assignment. I also created a secret and granted it "AuditLog.Read.All" API permission.
Now I am using the following code:
$TenantId = '<tenant id>'
$AzureADCred = Get-Credential -UserName <tenant id> -Message "Enter secret value"
Connect-AzAccount -ServicePrincipal -Credential $AzureADCred -TenantId $TenantId
$WorkspaceID = '<workspace id>'
$UserPrincipalName = 'user#domain.com'
#Create the query for log analytics workspace for last sign in for user which goes back 180 days
$query = 'SigninLogs | Where-Object TimeGenerated > ago(180d) | Where-Object UserPrincipalName == "' + $UserPrincipalName + '" | summarize signInCount = count() by UserPrincipalName | Sort-Object by signInCount desc'
#Create the query for log analytics workspace for top matched rules
$query = 'AzureDiagnostics | where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog" | summarize count() by ruleId_s, bin(TimeGenerated, 1m) | where count_ > 10 | render timechart'
$result = Invoke-AzOperationalInsightsQuery -WorkspaceId $WorkspaceID -Query $query
Disconnect-AzAccount
But I only get back:
Invoke-AzOperationalInsightsQuery : Operation returned an invalid
status code 'BadRequest'
What gives?

Azure PowerShell - get VM usage from across all subscriptions

I want to list all the VMs that generate costs in a specific timeframe or billing period.
I managed to create this script to get me the desired output:
$file="C:\temp\GeneratedCost-short.csv"
(az consumption usage list `
--start-date "2020-07-01" --end-date "2020-07-31" | ConvertFrom-Json)`
| Where-Object {$_.product -Match "Virtual Machines"}`
| Sort-Object -Property instanceName -Descending | Select-Object instanceName, subscriptionName`
| Get-Unique -AsString | ConvertTo-Csv -NoTypeInformation | Set-Content $file
But this will give me the output only for the current subscription.
How can I run on all the subscriptions that I have on the azure tenant?
I tried using the below version but it doesn't seem to work:
$file="C:\temp\GeneratedCost-short.csv"
$VMs = #()
$Subscriptions = Get-AzSubscription
foreach ($sub in $Subscriptions) {
Get-AzSubscription -SubscriptionName $sub.Name | az account set -s $sub.Name
$VMs += (az consumption usage list --start-date "2020-07-01" --end-date "2020-07-03" | ConvertFrom-Json)
}
#
$VMs | Where-Object {$_.product -Match "Virtual Machines"}`
| Sort-Object -Property instanceName -Descending | Select-Object instanceName, subscriptionName`
| Get-Unique -AsString | ConvertTo-Csv -NoTypeInformation | Set-Content $file
Any suggestions?
Mixing the Azure PowerShell module and Azure CLI could be causing issues with your code if the accounts haven't been retrieved between the two. Verify that az cli has the proper subscriptions
az account list -o table
If you don't see the accounts be sure to re-run az login.
Here's your code with the azure cli only
$file="C:\temp\GeneratedCost-short.csv"
$VMs = #()
az account list -o json | ConvertFrom-Json |
ForEach-Object {
Write-Host "Getting usage for account: " $_.Name
az account set -s $_.Name
$VMs += (az consumption usage list --start-date "2020-07-01" --end-date "2020-07-03" | ConvertFrom-Json)
}
$VMs | Where-Object {$_.product -Match "Virtual Machines"} |
Sort-Object -Property instanceName -Descending |
Select-Object instanceName, subscriptionName |
Get-Unique -AsString | ConvertTo-Csv -NoTypeInformation |
Set-Content $file
never do += on an array, worst pattern ever.
[System.Collections.Generic.List[PSObject]]$VMs = #()
$subs = Get-AzSubscription # | Where-Object {$_.State -eq 'Enabled'}
foreach ($s in $subs) {
Set-AzContext -SubscriptionObject $s | Out-Null
$vm = # your search here ...
$VMs.Add($vm)
}

Azure Powershell - Script to obtain VM info across subscriptions

Trying to run a script that will connect to each subscription, and pull the
$azureSubs = Get-AzureRMSubscription
$azureSubs | ForEach-Object {Select-AzureRMSubscription $_ | Out-Null; Get-AzureRMVM | select resourcegroupname, name, licensetype -WarningAction SilentlyContinue}
This works, BUT I'd like to add two more pieces of information: the "OSType" and "VMSize"
If I do a GET-AZURERMVM, in the table for that subscription that the command is run in, the two pieces of information I need are there: VmSize and OsType
However, when I try to add them to the query, the columns are blank.
I believe the VmSize is in the HardwareProfile, and OsType is in the OsProfile, as if I run a "Get-AzureRMVM -name (name) -resourcegroupname (RGname)", then it shows "Hardware Profile: VMSize" and "OSProfile: ComputerName, AdminUsername windowsConfiguration, Secrets"
Ultimate goal is to get the script that will, for each subscription, print results like:
ResourceGroupName | Name | License Type | VMSize | OS Type
TEST_RG | Test_VM | Windows_Server | DS3_v2 | Windows
Test_RG | Test_VM2 | | DS3_v2 | Linux
etc.
Thankful for any help; sorry for such a noob question. Have spent so much time trying to figure this out...
Something like the following would work.
What you were missing mainly was calculated properties.
This is what allow you to perform a select of custom property.
Some notes:
In your code, you used -WarningAction SilentlyContinue on the Select statement. You need to put it on the Get-AzureRMVM CmdLet instead.
This is my opinion but unless you are writing one-liners on purposes, try aerating your code more. It will make it way easier to read, debug and maintain.
This is the code you wrote, modified to include the calculated properties and with the WarningAction parameter set to Get-AzureRMVM instead of the Select statement.
$azureSubs = Get-AzureRMSubscription
$Vms = $azureSubs | ForEach-Object {Select-AzureRMSubscription $_ | Out-Null; Get-AzureRMVM -WarningAction SilentlyContinue | select resourcegroupname, name, licensetype, #{Name="VMSize";Expression={$_.HardwareProfile.VmSize}},#{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}}
$Vms | ft
The same thing, with some progress indication without forcing everything on one line.
$azureSubs = Get-AzureRMSubscription
$Vms = New-Object 'System.Collections.Generic.List[PSObject]'
ForEach ($sub in $azureSubs) {
Select-AzureRMSubscription $sub | Out-Null
Write-Host "Processing Subscription $($sub.Name)".PadRight(50,' ') -ForegroundColor Cyan -NoNewline
[PsObject[]]$items = Get-AzureRMVM -WarningAction SilentlyContinue |
select resourcegroupname,
name,
licensetype,
#{Name="VMSize";Expression={$_.HardwareProfile.VmSize}},
#{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}
Write-Host "($($items.count) retrieved)"
if ($items -ne $null) {
$vms.AddRange($items)
}
}
$vms | Format-Table
You are looking for something like this on the select side
select resourcegroupname, name, licensetype, #{Name="VMSize";Expression={$_.HardwareProfile.VmSize}}, #{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}

Office 365 - how to manage many users

I have 200 unsorted users in office 365. I want to find an easy way to manage who they are and what security group each user belongs to.
Is there an easy way to export username and what groups each user belongs to?
Iam quite new to poweshell...
But i want to export a CSV file with user and gruops.
Is this possible?
Or do you recommend any other way to quick get an overview of all users and what grups they belong to.
Some users need to be in multiple groups and i suspect some users are missing in groups they should be in..
Thanks for any tips i can get.
################################################################################################################################################################
# Script accepts 2 parameters from the command line
#
# Office365Username - Optional - Administrator login ID for the tenant we are querying
# Office365Password - Optional - Administrator login password for the tenant we are querying
#
#
# To run the script
#
# .\Get-DistributionGroupMembers.ps1 [-Office365Username admin#xxxxxx.onmicrosoft.com] [-Office365Password Password123]
#
#
# Author: Alan Byrne
# Version: 2.0
# Last Modified Date: 16/08/2014
# Last Modified By: Alan Byrne alan#cogmotive.com
################################################################################################################################################################
#Accept input parameters
Param(
[Parameter(Position=0, Mandatory=$false, ValueFromPipeline=$true)]
[string] $Office365Username,
[Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$true)]
[string] $Office365Password
)
#Constant Variables
$OutputFile = "DistributionGroupMembers.csv" #The CSV Output file that is created, change for your purposes
$arrDLMembers = #{}
#Remove all existing Powershell sessions
Get-PSSession | Remove-PSSession
#Did they provide creds? If not, ask them for it.
if (([string]::IsNullOrEmpty($Office365Username) -eq $false) -and ([string]::IsNullOrEmpty($Office365Password) -eq $false))
{
$SecureOffice365Password = ConvertTo-SecureString -AsPlainText $Office365Password -Force
#Build credentials object
$Office365Credentials = New-Object System.Management.Automation.PSCredential $Office365Username, $SecureOffice365Password
}
else
{
#Build credentials object
$Office365Credentials = Get-Credential
}
#Create remote Powershell session
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $Office365credentials -Authentication Basic –AllowRedirection
#Import the session
Import-PSSession $Session -AllowClobber | Out-Null
#Prepare Output file with headers
Out-File -FilePath $OutputFile -InputObject "Distribution Group DisplayName,Distribution Group Email,Member DisplayName, Member Email, Member Type" -Encoding UTF8
#Get all Distribution Groups from Office 365
$objDistributionGroups = Get-DistributionGroup -ResultSize Unlimited
#Iterate through all groups, one at a time
Foreach ($objDistributionGroup in $objDistributionGroups)
{
write-host "Processing $($objDistributionGroup.DisplayName)..."
#Get members of this group
$objDGMembers = Get-DistributionGroupMember -Identity $($objDistributionGroup.PrimarySmtpAddress)
write-host "Found $($objDGMembers.Count) members..."
#Iterate through each member
Foreach ($objMember in $objDGMembers)
{
Out-File -FilePath $OutputFile -InputObject "$($objDistributionGroup.DisplayName),$($objDistributionGroup.PrimarySMTPAddress),$($objMember.DisplayName),$($objMember.PrimarySMTPAddress),$($objMember.RecipientType)" -Encoding UTF8 -append
write-host "`t$($objDistributionGroup.DisplayName),$($objDistributionGroup.PrimarySMTPAddress),$($objMember.DisplayName),$($objMember.PrimarySMTPAddress),$($objMember.RecipientType)"
}
}
#Clean up session
Get-PSSession | Remove-PSSession

Resources